home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 2.toast / pc / sample code / overview / dave falkenburg's sprocket / experimental stuff / mailablewindow.cp < prev    next >
Encoding:
Text File  |  2000-09-28  |  6.8 KB  |  282 lines

  1. /*
  2.     File:        MailableWindow.cp
  3.  
  4.     Contains:    A AOCE-aware window base class
  5.  
  6.     Written by: Dave Falkenburg with help from Steve Falkenburg’s
  7.                 CollaboDraw “object oriented C” sample application.    
  8.  
  9.     Copyright:    Copyright © 1993-1999 by Apple Computer, Inc., All Rights Reserved.
  10.  
  11.                 You may incorporate this Apple sample source code into your program(s) without
  12.                 restriction. This Apple sample source code has been provided "AS IS" and the
  13.                 responsibility for its operation is yours. You are not permitted to redistribute
  14.                 this Apple sample source code as "Apple sample source code" after having made
  15.                 changes. If you're going to re-distribute the source, we require that you make
  16.                 it clear in the source that the code was descended from Apple sample source
  17.                 code, but that you've made changes.
  18.  
  19.     Change History (most recent first):
  20.                 8/19/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  21.                 9/27/94        DRF                Changes for Dave Mark: AppLib.h is now Sprocket.h.
  22.                 9/9/94        DRF                Reordered headers and removed redundant #includes and
  23.                                             conditionalize AOCE support.
  24.                 8/26/94        DRF                Added AdjustPerfectWindowSizeForMailer.
  25.  
  26. */
  27.  
  28. #include "Sprocket.h"
  29. #include "MailableWindow.h"
  30.  
  31. #if    qAOCEAware
  32.  
  33. TMailableWindow::TMailableWindow()
  34.     {
  35.     //    Remember, we can’t do anything in here because of C++’s insistance
  36.     //    of creating objects from the bottom-up.  If we call CreateWindow in
  37.     //    here then we end up calling the pure-virtual version of MakeNewWindow.
  38.  
  39.     fMailerIsAttached = false;
  40.     fMailerIsExpanded = false;
  41.     }
  42.  
  43.  
  44. TMailableWindow::~TMailableWindow()
  45.     {
  46. #if    qDebug
  47.     //    Release any PowerTalk things if they are still around
  48.  
  49.     if (fMailerIsAttached)
  50.         DebugStr("\pDidn’t call TMailableWindow::Close to dispose mailer");
  51. #endif
  52.     }
  53.  
  54.  
  55. Boolean
  56. TMailableWindow::EventFilter(EventRecord * anEvent)
  57.     {
  58.     if (gHasAOCE)
  59.         {
  60.         SMPMailerResult    whatHappened;
  61.         SMPMailerState    mailerState;
  62.         
  63.         (void) SMPMailerEvent(anEvent,&whatHappened,FrontWindowProcForAOCEUPP,0);
  64.         (void) SMPGetMailerState(fWindow,&mailerState);
  65.  
  66.         //    ALOT MORE STUFF GOES IN HERE!
  67.  
  68.         // track if the mailer has been expanded or contracted        
  69.         if ((whatHappened & kSMPContractedMask) != 0)
  70.             this->ExpandOrContractMailer(false);
  71.         else if ((whatHappened & kSMPExpandedMask) != 0)
  72.             this->ExpandOrContractMailer(true);
  73.  
  74.         // check to see if the app must handle this event
  75.         if ((whatHappened & kSMPAppMustHandleEventMask) != 0)
  76.             return false;
  77.         else
  78.             return true;    //    nope, PowerTalk dealt with the event, we don’t have to.
  79.         }
  80.  
  81.     return false;
  82.     }
  83.  
  84.  
  85. void
  86. TMailableWindow::CreateWindow(WindowType typeOfWindowToCreate /* = kNormalWindow */)
  87.     {
  88. #if    qDebug
  89.     //    You can’t put a mailer in a floating window or a modal window!
  90.  
  91.     if (typeOfWindowToCreate != kNormalWindow)
  92.         DebugStr("\pTMailableWindow: Must be normal windows");
  93. #endif
  94.  
  95.     TWindow::CreateWindow();
  96.     
  97.     if (gHasAOCE && gPreferences.fMailPreferences.fCreateMailerForNewDocuments)
  98.         this->AttachMailerToWindow(true);
  99.  
  100.     fContentRect = fWindow->portRect;
  101.     }
  102.  
  103.  
  104. Boolean
  105. TMailableWindow::Close(void)
  106.     {
  107.     Boolean    reallyClosing = true;
  108.     
  109.     if (fMailerIsAttached)
  110.         {
  111.         //    Offer to send or save the letter if it has changed
  112.  
  113.         }
  114.     else
  115.         {
  116.         //    Offer to save the document if it is dirty
  117.  
  118.         }
  119.  
  120.     if (fMailerIsAttached)
  121.         {
  122.         //    We need to remove the mailer before calling TWindow::Close
  123.         //    otherwise AOCE will get very confused. Too bad they didn’t
  124.         //    integrate better with the window manager to catch this for us.
  125.         
  126.         this->RemoveMailerFromWindow();
  127.         }
  128.  
  129.     if (reallyClosing)
  130.         return TWindow::Close();
  131.  
  132.     return false;
  133.     }
  134.  
  135.  
  136. OSErr
  137. TMailableWindow::AttachMailerToWindow(Boolean createExpanded)
  138.     {
  139.     Point    where = {0,0};
  140.     OSErr    err;
  141.         
  142.     err = SMPNewMailer(fWindow,where,kCanContract,createExpanded,kDefaultAuthIdentity,nil,0L);
  143.     fMailerIsAttached = (err == noErr);
  144.     fMailerIsExpanded = kInitiallyExpanded;
  145.     
  146.     return err;    
  147.     }
  148.  
  149.  
  150. OSErr
  151. TMailableWindow::RemoveMailerFromWindow(void)
  152.     {
  153.     OSErr                err = noErr;
  154.     SMPCloseOptions        closeOptions;
  155.     
  156.     closeOptions.moveToTrash = false;
  157.     closeOptions.addTag = false;
  158.     closeOptions.tag.dataLength = 0;
  159.     
  160.     if (fMailerIsAttached)
  161.         {
  162.         //    Get rid of the PowerTalk mailer header    
  163.         err = SMPDisposeMailer(fWindow,&closeOptions);
  164.         
  165.         fMailerIsAttached = false;
  166.         fContentRect = fWindow->portRect;
  167.         }
  168.         
  169.     return err;
  170.     }
  171.  
  172.  
  173. void
  174. TMailableWindow::Draw(void)
  175.     {
  176.     //    Because of SMPMailerEvent, the PowerTalk mailer, if present will be drawn by AOCE
  177.     //    This means the window’s draw method only needs to worry drawing the other content
  178.  
  179.     RgnHandle    originalClipRgn = NewRgn();
  180.     
  181.     GetClip(originalClipRgn);
  182.     ClipRect(&fContentRect);
  183.  
  184.     //    Possible optimization by checking content rect against visRgn
  185.     //    « we probably also want to do a wacky SetOrigin call here »    
  186.     this->DrawContents();
  187.  
  188.     SetClip(originalClipRgn);
  189.     DisposeRgn(originalClipRgn);
  190.     }
  191.  
  192.  
  193. void
  194. TMailableWindow::AdjustPerfectWindowSizeForMailer(Rect * perfectSize)
  195.     {
  196.     //    If a mailer is attached to the window, figure out how big it is
  197.     //    and make sure that the window is wide enough to deal with it.
  198.  
  199.     if (fMailerIsAttached)
  200.         {
  201.         short    expHeight,contHeight,mWidth;
  202.     
  203.         (void) SMPGetDimensions(&mWidth,&contHeight,&expHeight);    
  204.     
  205.         //    Make sure the perfect size is wide enough for the standard mailer.
  206.     
  207.         if (perfectSize->right < perfectSize->left + mWidth)
  208.             perfectSize->right = perfectSize->left + mWidth;
  209.  
  210.         //    We might also want to adjust height, but for now ignore the problem
  211.         }
  212.     }
  213.     
  214.  
  215. void
  216. TMailableWindow::AdjustForNewWindowSize(Rect * /* oldRect */,Rect * newRect)
  217.     {
  218.     //    NOTE: Assumes rect is always zero-based
  219.  
  220.     fContentRect.bottom = newRect->bottom;
  221.     fContentRect.right = newRect->right;
  222.     }
  223.  
  224.  
  225. void
  226. TMailableWindow::ExpandOrContractMailer(Boolean doExpand)
  227.     {
  228.     GrafPtr    oldPort;
  229.     Rect    prevContentRect, newContentRect;
  230.     short    expHeight,contHeight,mWidth;
  231.  
  232.     GetPort(&oldPort);
  233.     SetPort(fWindow);
  234.     
  235.     (void) SMPGetDimensions(&mWidth,&contHeight,&expHeight);    
  236.  
  237.     prevContentRect = fContentRect;
  238.     newContentRect = fWindow->portRect;
  239.  
  240.     if (doExpand)
  241.         newContentRect.top += expHeight;
  242.     else
  243.         newContentRect.top += contHeight;
  244.  
  245.     this->AdjustForNewContentRect(&prevContentRect,&newContentRect);
  246.     fContentRect = newContentRect;
  247.  
  248.     (void) SMPExpandOrContract(fWindow,doExpand);
  249.     fMailerIsExpanded = true;
  250.  
  251.     SetPort(oldPort);
  252.     }
  253.  
  254.  
  255. void
  256. TMailableWindow::AdjustForNewContentRect(Rect * /* prevContentRect */,Rect * newContentRect)
  257.     {
  258.     //    the default thing to do is to force a complete redraw of the window’s normal
  259.     //    content area. We could be clever and use scrollrect to keep the bits around,
  260.     //    but for now we cheeze out.
  261.     
  262.     InvalRect(newContentRect);
  263.     }
  264.  
  265. void
  266. TMailableWindow::DrawContents(void)
  267.     {
  268.     }
  269.  
  270.  
  271. //    FrontWindow custom procedure for AOCE standard mail package:
  272. //        It enables some of AOCE to cleanly interoperate with “Dean Yu”-style floating windows
  273.  
  274. pascal    WindowPtr
  275. FrontWindowProcForAOCE(long /* unusedParam */)
  276.     {
  277.     return MyFrontNonFloatingWindow();
  278.     }
  279.  
  280. FrontWindowUPP FrontWindowProcForAOCEUPP = NewFrontWindowProc(&FrontWindowProcForAOCE);
  281.  
  282. #endif